/** @brief File defining the scene viewer class.
 *
 * This file contains the definition of the scene visualiser class.
 *
 * @file Visualisation.hpp
 * @author Johan "Solo" Luisier
 * @date 2013/04/03
 */
#ifndef VISUALISATION_HPP
#define VISUALISATION_HPP

#include <QtGui/QGraphicsView>

class GridBase;
class RepresentationBase;

class QPointF;
class QWheelEvent;

/** @brief The Visualisation class
 *
 * @author Johan "Solo" Luisier
 * @date 2013/04/03
 *
 * @class Visualisation "Visualisation.hpp" "UI/Visualisation.hpp"
 */
class Visualisation : public QGraphicsView
{
    Q_OBJECT
public:
    explicit Visualisation( GridBase* model, RepresentationBase* scene, QWidget *parent = 0 );
    virtual ~Visualisation();

protected:
    /** @brief The logical representation of the grid.
     */
    GridBase* Model;
    /** @brief The visual items representing the grid.
     */
    RepresentationBase* Scene;
    /** @brief Current scaling factor.
     */
    qreal ZoomFactor;

    /**************************************************************************
     *
     * User interaction methods.
     *
     *************************************************************************/

    /** @brief The wheel interaction method.
     *
     * This method handles mouse wheel events on the widget. The wheel is used
     * to set the zoom.
     *
     * @param[in] event wheel move triggering the function call.
     *
     * @todo Implement the smarter way of doing it, with a delay and the
     * measurement of the ran angle.
     */
    void wheelEvent( QWheelEvent* event );
    /** @brief The key press interaction method.
     *
     * This method handles key strokes events. The behaviour of the widget is
     * of course key-dependent.
     *
     * @param[in] event key press event triggering the function call.
     */
    void keyPressEvent( QKeyEvent* event );
    /** @brief The key release interaction method.
     *
     * This method handles key strokes events. The behaviour of the widget is
     * of course key-dependent.
     *
     * @param[in] event key release event triggering the function call.
     */
    void keyReleaseEvent( QKeyEvent* event );
    /** @brief The mouse press event interaction method.
     *
     * This method handles mouse "click" events. In "panning" mode, the mother
     * class manages the movement.
     *
     * @param event
     */
    void mousePressEvent( QMouseEvent* event );
    /** @brief The mouse release event interaction method.
     *
     * This method handles mouse "click" events. In "panning" mode, the mother
     * class manages the movement.
     *
     * @param event
     */
    void mouseReleaseEvent( QMouseEvent* event );
    //void mouseDoubleClickEvent( QMouseEvent *event );
private:
    /** @brief Enumeration for the different navigation modes.
     *
     * The "navigation mode" sets the behaviour of the mouse interactions with
     * the widget.
     */
    enum NavMode
    {
        /** Default mode, the mouse cannot interact with the
        widget (except for the wheel).
         */
        Default = -1,
        /** Mode used for moving the view.
         */
        Panning = 0,
        /** Mode used to interact with the cells.
         */
        Editing = 1
    };

    /** @brief Stores the current navigation mode.
     */
    NavMode CurrentMode;

    /** @brief Defines the magnitude of the zoom for a wheel step.
     */
    static const qreal ScaleFactor;
signals:
    /** @brief The clicked signal.
     *
     * This signal is sent in Editing mode, and should be connected to the
     * appropriate slot in the representation instance, in order to determine
     * which was the clicked Cell instance.
     *
     * @param[out] pt coordinates of the point, in the QGraphicsScene.
     */
    void clickedAt( const QPointF& pt );
};

#endif // VISUALISATION_HPP
